<?php

namespace ImgMerge;

use Exception;
class ImgMerge
{

    public $fontColor = '#000000';
    public $fontSize = '20';
    public $fontType = '';
    public $font = [];
    public $sealImg = '';
    public $savePath = '';
    protected $fileName = '';
    protected $dst_w = '';
    protected $dst_h = '';
    protected $dst_type = '';
    protected $imgObj = '';

    /**
     *
     * 图片合成
     * @param string $baseImgPath 原始图片
     * @param string $fileName  导出文件名称（空为导出数据流）
     * @param string|array $sealImg 待合成图片 图片地址默认合成再右下角 or 数组 ['path'=>'图片地址','location'=>'lt(l:左，r:右，t:上，b:下，c:中)|[x,y]']  TODO 暂不支持location为字符串
     * @param array $font 待添加的文字 （二维数组） eg:[['text'=>'test','location'=>'[x,y],'size'=>'20','color'=>'#000000','font'=>'simli']]
     * @return string 如果保存到服务器 返回路径+文件名
     */
    public function index($baseImgPath='', $fileName = '', $sealImg='', $font=[])
    {
        $this->fileName = $fileName;
        try {
            return $this->merge($baseImgPath, $sealImg, $font);
        }  catch (Exception $e) {
            echo $e->getMessage();
        }
    }



    protected function fontMerge($font)
    {

        if (!is_array($font)){
            throw new Exception('The type of font param must be Array！');
        }

        foreach($font as $k=>$v){
            if (!is_array($v)){
                throw new Exception('The type of font param must be Array！');
            }
            $text = array_key_exists('text',$v)?$v['text']:'';
            $size = array_key_exists('size',$v)?$v['size']:$this->fontSize;
            $font = array_key_exists('font',$v)?$v['font']:$this->fontType;


            if(empty($font)){
                $font = dirname(__DIR__).'/fonts/simsun.ttf';
            }else{
                if (file_exists(dirname(__DIR__).'/fonts/'.$font.'.ttf')) {
                    $font = dirname(__DIR__).'/fonts/'.$font.'.ttf';
                }elseif (file_exists('C:/Windows/Fonts/'.$font.'.ttf')) {
                    $font = 'C:/Windows/Fonts/'.$font.'.ttf';
                }elseif (file_exists('./fonts/'.$font.'.ttf')) {
                    $font = './fonts/'.$font.'.ttf';
                    $font = realpath($font);
                }else{
                    throw new Exception('The fonts is unknow!');
                }
            }


            if (array_key_exists('location',$v)){
                $x = $v['location'][0];
                $y = $v['location'][1];
            }else{
                $x = $y = 0;
            }
            if (array_key_exists('color',$v)){
                $colorArr = $this->hexToRGB($v['color']);
            }else{
                $colorArr = $this->hexToRGB($this->fontColor);
            }
            $color = imagecolorallocate($this->imgObj, $colorArr['r'], $colorArr['g'], $colorArr['b']);
            imagefttext($this->imgObj, $size, 0, $x, $y, $color, $font, $text);
        }
    }

    protected function hexToRGB($fontColor)
    {
        $color = str_replace('#', '', $fontColor);
        if (strlen($color) > 3) {
            $rgb = array(
                'r' => hexdec(substr($color, 0, 2)),
                'g' => hexdec(substr($color, 2, 2)),
                'b' => hexdec(substr($color, 4, 2))
            );
        } else {
            $r = substr($color, 0, 1) . substr($color, 0, 1);
            $g = substr($color, 1, 1) . substr($color, 1, 1);
            $b = substr($color, 2, 1) . substr($color, 2, 1);
            $rgb = array(
                'r' => hexdec($r),
                'g' => hexdec($g),
                'b' => hexdec($b)
            );
        }
        return $rgb;
    }

    protected function merge($baseImgPath,$sealImgPath='', $font=[])
    {
        if (!file_exists($baseImgPath)){
            throw new Exception('file not find！');
        }
        if ($sealImgPath == '' && $font == ''){
            throw new Exception('输入第二参数！');
        }
        $this->imgObj = imagecreatefromstring(file_get_contents($baseImgPath));
        list($this->dst_w, $this->dst_h, $this->dst_type) = getimagesize($baseImgPath);

        if ($sealImgPath != ''){
            $this->imgMerge($sealImgPath);
        }
        if (!empty($font)){
            $this->fontMerge($font);
        }

        header("Content-Type:text/html;charset=utf-8");
        switch ($this->dst_type) {
            case 1://GIF
                header('Content-Type: image/gif');
                if (empty($this->savePath)){
                    $this->fileName == ''?:header("Content-Disposition: attachment;filename={$this->fileName}.gig");
                    imagegif($this->imgObj);
                    ob_end_flush();
                }else{
                    if (empty($this->fileName)) {
                        throw new Exception('The file name must exists when save !');
                    }
                    if (!is_dir($this->savePath)){
                        mkdir($this->savePath);
                        // throw new Exception('The savePath not exists !');
                    }
                    imagegif($this->imgObj,$this->savePath.'/'.$this->fileName.'.git');
                    return $this->savePath.'/'.$this->fileName.'.git';
                }
                break;
            case 2://JPG
                header('Content-Type: image/jpeg');
                if (empty($this->savePath)){
                    $this->fileName == ''?:header("Content-Disposition: attachment;filename={$this->fileName}.jpg");
                    imagejpeg($this->imgObj);
                    ob_end_flush();
                }else{
                    if (empty($this->fileName)) {
                        throw new Exception('The file name must exists when save !');
                    }
                    if (!is_dir($this->savePath)){
                        mkdir($this->savePath);
                        // throw new Exception('The savePath not exists !');
                    }
                    imagejpeg($this->imgObj,$this->savePath.'/'.$this->fileName.'.jpg');
                    return $this->savePath.'/'.$this->fileName.'.jpg';
                }
                break;
            case 3://PNG
                header('Content-Type: image/png');
                if (empty($this->savePath)){
                    $this->fileName == ''?:header("Content-Disposition: attachment;filename={$this->fileName}.png");
                    imagepng($this->imgObj);
                    ob_end_flush();
                }else{
                    if (empty($this->fileName)) {
                        throw new Exception('The file name must exists when save !');
                    }
                    if (!is_dir($this->savePath)){
                        mkdir($this->savePath);
                        // throw new Exception('The savePath not exists !');
                    }
                    imagepng($this->imgObj,$this->savePath.'/'.$this->fileName.'.png');
                    return $this->savePath.'/'.$this->fileName.'.png';
                }
                break;
            default:
                break;
        }
        imagedestroy($this->imgObj);

    }

    /**
     * [
     * ['path'=>'a.png','location'=>'lt|[x,y]']
     * ]
     * @param $sealImgPath
     * @throws Exception
     */
    protected function imgMerge($sealImgPath)
    {
        if (is_string($sealImgPath)){
            if (!file_exists($sealImgPath)){
                throw new Exception('file not find！');
            }
            $sealImg = imagecreatefromstring(file_get_contents($sealImgPath));

            list($sea_w, $sea_h, $sea_type) = getimagesize($sealImgPath);
            imagecopyresampled($this->imgObj, $sealImg, $this->dst_w-$sea_w, $this->dst_h-$sea_h, 0, 0, $sea_w, $sea_h, $sea_w, $sea_h);
        }else{
            if (empty($sealImgPath)){
                return false;
            }

            foreach($sealImgPath as $v){

                $sealImg = imagecreatefromstring(file_get_contents($v['path']));
                list($sea_w, $sea_h, $sea_type) = getimagesize($v['path']);

                if (array_key_exists('location',$v)){
                    if (is_string($v['location'])){
                        //TODO
                        // $location = $this->getLocation($v['location']);
                        // imagecopyresampled($this->imgObj, $sealImg, $v['location'][0], $v['location'][1], 0, 0, $sea_w, $sea_h, $sea_w, $sea_h);
                    }elseif (is_array($v['location'])){
                        imagecopyresampled($this->imgObj, $sealImg, $v['location'][0], $v['location'][1], 0, 0, $sea_w, $sea_h, $sea_w, $sea_h);
                    }else{
                        throw new Exception('location param error！');
                    }
                }else{
                    list($sea_w, $sea_h, $sea_type) = getimagesize($v['path']);
                    imagecopyresampled($this->imgObj, $sealImg, $this->dst_w-$sea_w, $this->dst_h-$sea_h, 0, 0, $sea_w, $sea_h, $sea_w, $sea_h);
                }

            }
        }
    }
}
